package org.oos.dao.lists.impl;

import java.io.File;

import org.oos.atom.AtomEntity;
import org.oos.atom.impl.AtomFeed;
import org.oos.dao.Dao;
import org.oos.dao.exceptions.DeleteException;
import org.oos.lists.DynamicList;

/**
 * 
 * Extension of {@link ReadOnlyDynamicList} that provides with write privileges
 * to the wrapped atom service.
 * 
 * @author pablo.gonzalez@11870.com
 * 
 * @param <Entity>
 * @param <Feed>
 */
public class FullAccessDynamicList<Entity extends AtomEntity, Feed extends AtomFeed<Entity>>
		extends ReadOnlyDynamicList<Entity, Feed> implements
		DynamicList<Entity> {

	private static final long serialVersionUID = -1692263252424717450L;

	public FullAccessDynamicList(Dao<Entity, Feed> dao, Feed feed) {
		super(dao, feed);
	}

	@Override
	public void add(int index, Entity element) {
		try {
			dao.create(element);
			buffer.add(index, element);
		} catch (Exception e) {
			dao.getLog().throwing(getClass().getSimpleName(), "add(int, Entity)", e);
			throw new RuntimeException(e);
		}
	}

	@Override
	public boolean add(Entity entity) {
		try {
			Entity newEntity = dao.create(entity);
			if (newEntity != null) {

				// TODO don't like to have to do this... Must review
				buffer.add(0, newEntity);
				totalSize += 1;
				// int bufferSize = buffer.size();
				// buffer.clear();
				// get(bufferSize);
				return true;
			}
		} catch (Exception e) {
			dao.getLog().throwing(getClass().getSimpleName(), "add(Entity)", e);
			throw new RuntimeException(e);
		}
		return false;
	}
	
	public boolean addMedia(File file, String contentType) {
		try {
			Entity newEntity = dao.createMedia(file, contentType);
			if (newEntity != null) {
				buffer.add(0, newEntity);
				totalSize += 1;
				return true;
			}
		} catch (Exception e) {
			dao.getLog().throwing(getClass().getSimpleName(), "addMedia(File, String)", e);
			throw new RuntimeException(e);
		}
		return false;
	}

	@Override
	public Entity set(int index, Entity entity) {
		try {
			dao.update(entity);
			buffer.set(index, entity);
			return entity;
		} catch (Exception e) {
			dao.getLog().throwing(getClass().getSimpleName(), "set(Entity)", e);
			throw new RuntimeException(e);
		}
	}

	@Override
	public Entity remove(int index) {
		try {
			Entity entity = dao.read(index);
			dao.delete(entity);
			buffer.remove(entity);
			totalSize -= 1;
			return entity;
		} catch (Exception e) {
			dao.getLog().throwing(getClass().getSimpleName(), "remove(Entity)",
					e);
			throw new RuntimeException(e);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean remove(Object o) {
		try {
			return remove((Entity) o);
		} catch (ClassCastException e) {
			return super.remove(o);
		}
	}

	public boolean remove(Entity entity) {
		try {
			dao.delete(entity);
			buffer.remove(entity);
			totalSize -= 1;
		} catch (DeleteException e) {
			throw new RuntimeException(e);
		}
		return super.remove(entity);
	}

	@Override
	public FullAccessDynamicList<Entity, Feed> clone()
			throws CloneNotSupportedException {
		return (FullAccessDynamicList<Entity, Feed>) super.clone();
	}

}
